﻿using System;
using System.Collections.Generic;
using System.Text;
using Ripper;
using System.Windows.Forms;
using System.IO;
using System.CodeDom.Compiler;

namespace CD2WebAudio3Lib
{
    public class main_functions :  IDisposable
    {
        private static CDDrive m_CDDrive;
        private bool m_CDLoaded = false;
        private static string m_DriveLetter = string.Empty;
        private TempFileCollection m_TempFiles = null;
        private static main_functions m_Instance = null;

        private main_functions()
        {
            m_CDDrive = new CDDrive();
        }

        public static main_functions Get_Instance()
        {
            if (m_Instance == null)
            {
                m_Instance = new main_functions();
            }
            return m_Instance;
        }

        public string[] Load_Drives()
        {
            char[] drives = CDDrive.GetCDDriveLetters();
            string[] returnval = new string[drives.Length];

            
            for (int i = 0; i < drives.Length; i++)
            {
                returnval[i] = drives[i].ToString();
            }

            return returnval;
        }

        /// <summary>
        /// Returns the path to the executable file, with a \ on the end
        /// </summary>
        public string AppPath
        {
            get
            {
                string path = System.Windows.Forms.Application.ExecutablePath;
                path = path.Substring(0, path.LastIndexOf(@"\") + 1);
                return path;
            }
        }

        public string CommonAppData
        {
            get
            {
                string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                path = path.Substring(0, path.LastIndexOf(@"\") + 1);
                path += "CD2WebAudio3\\";
                return path;
            }
        }

        public track_list Load_Tracks(string pDriveLetter)
        {
            track_list returnVal = new track_list();


            // open the drive
            Get_CDDrive(pDriveLetter);

            // if open then
            if (m_CDDrive.IsOpened)
            {
                if (m_CDDrive.IsCDReady())
                {
                    if (!m_CDLoaded)
                    {
                        if (m_CDDrive.Refresh())
                        {

                            int Tracks = m_CDDrive.GetNumTracks();
                            ListViewItem[] items = new ListViewItem[Tracks];

                            for (int i = 1; i <= Tracks; i++)
                            {
                                int seconds = bytes_To_Seconds(m_CDDrive.TrackSize(i));
                                ListViewItem item = new ListViewItem(new string[] { i.ToString(), Seconds_To_Time(seconds), m_CDDrive.IsAudioTrack(i) ? "audio" : "data", seconds.ToString() });
                                if (m_CDDrive.IsAudioTrack(i)) item.Checked = true;
                                items[i-1] = item;
                            }
                            m_CDLoaded = true;

                            returnVal.Items = items;
                            returnVal.ClearList = true;
                        }
                        else m_CDLoaded = false;
                    }
                }
                else
                {
                    returnVal.ClearList = true;
                    m_CDDrive.Close();
                    m_CDLoaded = false;
                }
            }
            else
            {
                returnVal.ClearList = true;
                m_CDLoaded = false;
            }

            return returnVal;
        }

        /// <summary>
        /// Converts seconds to displayable time string.
        /// </summary>
        /// <param name="pSeconds">Number of seconds</param>
        /// <returns>Formatted time string</returns>
        public string Seconds_To_Time(int pSeconds)
        {
            string returnVal = string.Empty;

            DateTime dt = new DateTime(2000, 1, 1, 0, 0, 0);
            dt = dt.AddSeconds(pSeconds);

            if (dt.Hour > 0)
            {
                returnVal = dt.ToString("h:mm:ss");
            }
            else
            {
                returnVal = dt.ToString("m:ss");
            }

            return returnVal;
        }

        /// <summary>
        /// Converts number of bytes of CD audio to seconds.
        /// </summary>
        /// <param name="pBytes">Length of CD audio in bytes</param>
        /// <returns>Duration of CD audio in seconds</returns>
        private int bytes_To_Seconds(uint pBytes)
        {
            return Convert.ToInt32((decimal)(Convert.ToDecimal(pBytes) / 176400));
        }

        public static CDDrive Get_CDDrive(string pDriveLetter)
        {
            if (!m_CDDrive.IsOpened) m_CDDrive.Open(pDriveLetter[0]);
            else if (pDriveLetter != m_DriveLetter) 
            {
                m_CDDrive.Close();
                m_CDDrive.Open(pDriveLetter[0]);
            }

            m_DriveLetter = pDriveLetter;

            return m_CDDrive;
        }

        /// <summary>
        /// Returns a unique temp file name that does not already exist and adds it to the TempFiles collection.
        /// </summary>
        /// <param name="pExtension">The file extension.  Can be blank.</param>
        /// <returns>The file name.</returns>
        public string Get_Temp_FileName(string pExtension, bool pKeep)
        {
            // get the path
            string path = System.IO.Path.GetTempPath();
            if (!path.EndsWith(@"\")) path += @"\";
            path += @"CD2WebAudio3\";
            if (!Directory.Exists(path)) Directory.CreateDirectory(path);

            // get the extension
            string extension = pExtension;
            if (extension.Length == 0) extension = ".tmp";
            if (!extension.StartsWith(".")) extension = "." + extension;

            // get a file name that does not already exist
            int i = 0;
            string fileName = path + "~cd2web" + i.ToString().PadLeft(4, "0"[0]) + extension;

            while (System.IO.File.Exists(fileName))
            {
                i += 1;
                fileName = path + "~cd2web" + i.ToString().PadLeft(4, "0"[0]) + extension;
            }

            // add the file to the temp collection
            TempFiles.AddFile(fileName, pKeep);

            return fileName;

        }

        /// <summary>
        /// Returns the temp file collection for the application
        /// </summary>
        public TempFileCollection TempFiles
        {
            get
            {
                if (m_TempFiles == null) m_TempFiles = new TempFileCollection();
                return m_TempFiles;
            }
            set { m_TempFiles = value; }
        }

        /// <summary>
        /// Returns a file name with the indicated extension that does not exist.
        /// </summary>
        /// <param name="pExtension"></param>
        /// <returns>File Name</returns>
        public string Get_Target_File_Name(string pDestination, DateTime pSelectedDate, string pSuffix, string pExtension, bool pRenameIfExists)
        {
            // get the destination folder
            if (pDestination.Length < 3)
            {
                pDestination = AppPath + @"Output\"; 
            }

            // make sure the folder exists
            DirectoryInfo dir = new DirectoryInfo(pDestination);
            if (!dir.Exists) dir.Create();

            // build the file name
            if (!pDestination.EndsWith(@"\")) pDestination += @"\";
            if (!pExtension.StartsWith(".")) pExtension = "." + pExtension;
            pDestination += pSelectedDate.ToString("yyyyMMdd") + pSuffix.Trim() + pExtension;

            // if the file exists, rename it
            FileInfo fi = new FileInfo(pDestination);
            if ((fi.Exists) && (pRenameIfExists)) fi.MoveTo(pDestination + "." + DateTime.Now.ToString("yyyyMMddhhmmss"));

            // return
            return pDestination;

        }

        

        public void Dispose()
        {
            if (m_TempFiles != null)
            {
                m_TempFiles.Delete();
            }
        }

    }

    public class track_list
    {
        public ListViewItem[] Items = null;
        public bool ClearList = false;
    }
}
